package org.gnuhpc.activity;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.gnuhpc.R;
import org.gnuhpc.adapter.EfficientAdapter;

import android.R.integer;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class Search extends Activity implements OnClickListener{
	private static double lat;
    private static double lon;
    private static final String LOG_TAG = "ShowLocation";
    private final int UPDATE_UI = 1;
    private final int NO_RESULT = 2;
    private final int SERVICE_UNAVAILABLE = 3;
    private String[] addresses = {};
    private String[] latlons = {}; 
    private ListView locationListView;
    private EditText placeText;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Address address;
		super.onCreate(savedInstanceState);
		setContentView(R.layout.search);
		View searchButton = (Button) findViewById(R.id.lookup_button);
		placeText = (EditText)findViewById(R.id.lookup_input);
		
		searchButton.setOnClickListener(this);
		locationListView = (ListView)findViewById(R.id.lookup_listview);
		locationListView.setEmptyView(findViewById(R.id.empty));
		
		ColorDrawable divDrawable = new ColorDrawable(Color.DKGRAY);
		locationListView.setDivider(divDrawable);
		locationListView.setDividerHeight(2);
		
		locationListView.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				String latlon = latlons[arg2];
				String temp[] = latlon.split("\n");
				lat = Double.parseDouble(temp[0]);
				lon = Double.parseDouble(temp[1]);
				Intent j = new Intent();
				j.putExtra("lat", lat);
				j.putExtra("lon", lon);		   
		        Log.d(LOG_TAG, "Lat: " + lat + "Lon: " + lon + " Temp:" + temp[0]+ " "+temp[1]);		        
		        setResult(RESULT_OK, j);
		        finish();
			}
		});
		if (getIntent().getExtras()!=null) {
			switch (getIntent().getExtras().size()) {
			case 0:
				break;
			case 1:
				final String searchString = getIntent().getExtras().getString("SEARCH");			
				searchHandler(searchString);
				break;		

			default:			
				addresses = getIntent().getExtras().getStringArray("ADDRESS");
				latlons = getIntent().getExtras().getStringArray("LOCATION");
				mHandler.sendEmptyMessage(UPDATE_UI);
				break;
			}
		}		
	}

	 private Handler mHandler = new Handler(){
		 public void handleMessage(Message msg) {
			 switch (msg.what) {
			case UPDATE_UI:
				locationListView.setAdapter(new EfficientAdapter(Search.this,latlons,addresses));
				break;
			case NO_RESULT:
				Toast.makeText(Search.this, "No Result returned!", Toast.LENGTH_SHORT).show();
				break;
			case SERVICE_UNAVAILABLE:
				Toast.makeText(Search.this, "Service Unavailable!", Toast.LENGTH_SHORT).show();
				break;
			default:
				break;
			}
		 };
	 };
	
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.lookup_button:
			
			final String placeName = placeText.getText().toString();
			if (placeName.equals("")) {
				break;
			}
			Thread getLocationThread = new Thread(new Runnable() {				
					public void run() {
						getLocaton(placeName);					
					}
				});
			getLocationThread.start();
			
			break;

		default:
			break;
		}	
	}
	
	private void getLocaton(String placeName)
	{
		int numberOptions = 8;
		Geocoder gcoder = new Geocoder(this);
		try {
			List<Address> resultAddresses =  gcoder.getFromLocationName(placeName, numberOptions);
			Log.d(LOG_TAG, "Address: " + resultAddresses +" Place:" + placeName);
			
			if (resultAddresses.isEmpty()) {
				mHandler.sendEmptyMessage(NO_RESULT);				
			}
			else if(resultAddresses.size()>1){
				createListView(resultAddresses);
			}
			else {
				lat = resultAddresses.get(0).getLatitude();
				lon = resultAddresses.get(0).getLongitude();
				Intent j = new Intent();
				j.putExtra("lat", lat);
				j.putExtra("lon", lon);		        
		        Log.d(LOG_TAG, "Lat: " + lat + "Lon: " + lon);
		        setResult(RESULT_OK, j);

		        finish();
			}
		} catch (Exception e) {
			mHandler.sendEmptyMessage(SERVICE_UNAVAILABLE);
			Log.e("Geocoder", "I/O Failure; is network available?",e);
		}		
	}

	private void createListView(List<Address> resultAddresses) {
		int i=0;
		
		addresses = new String[resultAddresses.size()]; 
		latlons = new String[resultAddresses.size()];
		
		Iterator<Address> addressIterator = resultAddresses.iterator();
		while (addressIterator.hasNext()) {
			StringBuilder sb = new StringBuilder();
			Address location = addressIterator.next();
			for (int j = 0; j < location.getMaxAddressLineIndex(); j++) {			
				Log.d(LOG_TAG, "j:"+j +" address:" + location.getAddressLine(j));
				sb.append(location.getAddressLine(j));
			}			
			sb.append("\n").append(location.getLocality()).append("\n");
			if(location.getFeatureName()!=null){
				sb.append(location.getFeatureName()).append("\n");
			}
			sb.append(location.getCountryName());
			addresses[i]=sb.toString();
			latlons[i] = new String(location.getLatitude()+"\n"+location.getLongitude()); 
			Log.d(LOG_TAG, "i:"+i +" address:" + addresses[i] + " latlons" + latlons[i]);
			i++;
		}		
		mHandler.sendEmptyMessage(UPDATE_UI);
	}
	
	private void searchHandler(final String searchString){
		
		placeText.setText(searchString);
		if (searchString.equals("")) {
			return;
		}
		Thread getLocationThread = new Thread(new Runnable() {				
				public void run() {
					getLocaton(searchString);					
				}
			});
		getLocationThread.start();		
	}
}
